<?php

declare( strict_types = 1 );

namespace App\Common\Model\Base\DataUnit;

use App\Common as com;
use App\Common\Model as nameModel;
use App\Common\Model\Base\DataUnit as nameDataUnit;
use App\Common\Model\Base\DataUnit\DataOperates as nameDataOperates;
use App\Common\Model\Base\DataUnit\DataOperate as nameDataOperate;
use App\Common\Model\Base as nameBase;

class DataOperates extends nameDataUnit\Base {

	use com\Cla\ClaBase\Traits\GoPool;

	private array $dataOperateData;

	/**
	 * @param nameBase\DataUnit $dataUnit
	 * @param array $dataOperateData
	 */
	public function __construct( nameBase\DataUnit $dataUnit, array $dataOperateData ) {
		$this->dataOperateData = $dataOperateData;
		//
		parent::__construct( $dataUnit );
	}

	/**
	 * @return DataOperates\FieldStruct
	 * @throws
	 */
	public function goFieldStruct(  ):nameDataOperates\FieldStruct {
		return $this->goPool( __FUNCTION__, function(){
			return new nameDataOperates\FieldStruct( $this->dataOperateData );
		} );
	}

	/**
	 * sum
	 * @param string $fieldName
	 * @return mixed
	 */
	public function min( string $fieldName ):mixed {
		$model = $this->getDataUnit()->goModelQueryCloneOfNew();
		return $model->min( com\Lib\Fun\Str::parseName( $fieldName ) );
	}

	/**
	 * sum
	 * @param string $fieldName
	 * @return mixed
	 */
	public function max( string $fieldName ):mixed {
		$model = $this->getDataUnit()->goModelQueryCloneOfNew();
		return $model->max( com\Lib\Fun\Str::parseName( $fieldName ) );
	}

	/**
	 * sum
	 * @param string $fieldName
	 * @return mixed
	 */
	public function sum( string $fieldName ):mixed {
		$model = $this->getDataUnit()->goModelQueryCloneOfNew();
		return $model->sum( com\Lib\Fun\Str::parseName( $fieldName ) );
	}

	/**
	 * 自增
	 * @param string $fieldName
	 * @param float|int $num 递增值
	 * @param array $extra 指定要更新的字段，如：['name' => 'John']
	 * @return int 变化的行数
	 */
	public function increment( string $fieldName, float|int $num = 1, array $extra = [] ):int {
		$model = $this->getDataUnit()->goModelQueryCloneOfNew();
		return $model->increment( com\Lib\Fun\Str::parseName( $fieldName ), $num, $extra );
	}

	/**
	 * 自减
	 * @param string $fieldName
	 * @param float|int $num 递减值
	 * @return int 变化的行数
	 */
	public function decrement( string $fieldName, float|int $num = 1 ):int {
		$model = $this->getDataUnit()->goModelQueryCloneOfNew();
		return $model->decrement( com\Lib\Fun\Str::parseName( $fieldName ), $num );
	}

	/**
	 * 获取数据
	 * @param string $fieldName
	 * @param mixed $defaultValue 默认值
	 * @return mixed|null [{null}]数据不存在
	 */
	public function get( string $fieldName, mixed $defaultValue = null ):mixed {
/*		if( $this->goFieldStruct()->isset( $fieldName ) ){
			return $this->goFieldStruct()->getValue( $fieldName );
		}*/
		return $this->getDataUnit()->gowDirectData()->get( com\Lib\Fun\Str::parseName( $fieldName ), $defaultValue );
		/*
		// 如果有where则读取数据库
		if( $this->getDataUnit()->goDirectData()->isExistsWhere() ){
			return $this->getDataUnit()->goDirectData()->get( com\Lib\Fun\Str::parseName( $fieldName ), $defaultValue );
		}else{
			throw com\Lib\Err\Exception::makeOfNew( '没输入where条件', com\Lib\Err\Code::$sysDataNotExist );
		}
		*/
	}

	/**
	 * 获取数据
	 * @param array|null $fieldNames 返回字段 [null]全部
	 * @return array|null [{null}]数据不存在 [{array}]数据组
	 */
	public function gets( array|null $fieldNames = null ) {
		return $this->getDataUnit()->gowDirectData()->gets( is_array( $fieldNames ) ? com\Lib\Fun\Str::parseNames( $fieldNames ) : $fieldNames );
		/*
		// 如果有where则读取数据库
		if( $this->getDataUnit()->goDirectData()->isExistsWhere() ){

		}else{
			throw com\Lib\Err\Exception::makeOfNew( '没输入where条件', com\Lib\Err\Code::$sysDataNotExist );
		}
		*/
	}

	/**
	 * 获取设置的数据
	 * @param string $fieldName
	 * @param mixed $defaultValue 默认值
	 * @return mixed
	 */
	public function getSetData( string $fieldName, mixed $defaultValue = null ):mixed {
		if( $this->goFieldStruct()->isset( $fieldName ) ){
			return $this->goFieldStruct()->getValue( $fieldName );
		}
		//
		return $defaultValue;
	}

	/**
	 * 获取设置的数据(从重置数据中获取)
	 * @param string $fieldName
	 * @return mixed
	 * @throws
	 */
	public function getSetDataAsResetOrFail( string $fieldName ):mixed {
		return $this->goFieldStruct()->getValueAsResetOrFail( $fieldName );
	}

	/**
	 * 获取设置的数据(原始)
	 * @param string $fieldName
	 * @param mixed $defaultValue 默认值
	 * @return mixed
	 */
	public function getSetOriginalData( string $fieldName, mixed $defaultValue = null ):mixed {
		if( $this->goFieldStruct()->isset( $fieldName ) ){
			return $this->goFieldStruct()->getOriginalValue( $fieldName );
		}
		//
		return $defaultValue;
	}

	/**
	 * 获取设置的数据(不存在则抛出异常)
	 * @param string $fieldName
	 * @return mixed
	 * @throws
	 */
	public function getSetDataOrFail( string $fieldName ):mixed {
		if( $this->isset( $fieldName ) ){
			return $this->goFieldStruct()->getValue( $fieldName );
		}else{
			throw com\Lib\Err\Exception::makeOfNew( '未设置值', com\Lib\Err\Code::$sysDataNotExist );
		}
	}

	/**
	 * 获取数据(优化获取SetData，不存在则获取数据库)
	 * @param string $fieldName
	 * @param mixed $defaultValue 默认值
	 * @return mixed
	 * @throws
	 */
	public function getLayerData( string $fieldName, mixed $defaultValue = null ):mixed {
		if( $this->goFieldStruct()->isset( $fieldName ) ){
			return $this->goFieldStruct()->getValue( $fieldName );
		}
		// 如果有where则读取数据库
		if( $this->getDataUnit()->gowDirectData()->isExistsWhere() ){
			return $this->getDataUnit()->gowDirectData()->get( com\Lib\Fun\Str::parseName( $fieldName ), $defaultValue );
		}
		// 读取默认
		$data = $this->getDefaultValue( $fieldName );
		if( $data !== null ){
			return $data;
		}
		//
		return $defaultValue;
	}

	/**
	 * 获取数据(为null时抛出异常)
	 * @param string $fieldName
	 * @return mixed
	 * @throws
	 */
	public function getOrFail( string $fieldName ):mixed {
		return $this->getDataUnit()->gowDirectData()->getOrFail( com\Lib\Fun\Str::parseName( $fieldName ) );
	}

	/**
	 * 获取数据(从缓存中获取)
	 * @param string $fieldName
	 * @param mixed $default 默认数据
	 * @param bool $isForce 是否强制刷新数据访问。[false][默认]
	 * @return mixed
	 */
	public function getOfCache( string $fieldName, mixed $default = null, bool $isForce = false ):mixed {
		return $this->getDataUnit()->gowDirectData()->getOfCache( com\Lib\Fun\Str::parseName( $fieldName ), $default, $isForce );
		/*
		// 如果有where则读取数据库
		if( $this->getDataUnit()->goDirectData()->isExistsWhere() ){
			return $this->getDataUnit()->goDirectData()->getOfCache( $fieldName, $isForce );
		}
		// 读取默认
		return $this->getDefaultValue();
		*/
	}

	/**
	 * 获取数据(从缓存中获取)
	 * 注：与getOfCache功能一致，建议使用getOfCache
	 * @param string $fieldName
	 * @param mixed $default 默认数据
	 * @param bool $isForce 是否强制刷新数据访问。[false][默认]
	 * @return mixed
	 */
	public function getOfCaches( string $fieldName, mixed $default = null, bool $isForce = false ):mixed {
		return $this->getDataUnit()->gowDirectData()->getOfCache( com\Lib\Fun\Str::parseName( $fieldName ), $default, $isForce );
		// return $this->getDataUnit()->goDirectData()->getOfCaches( com\Lib\Fun\Str::parseName( $fieldName ), $default, $isForce );
		/*
		// 如果有where则读取数据库
		if( $this->getDataUnit()->goDirectData()->isExistsWhere() ){
			return $this->getDataUnit()->goDirectData()->getOfCache( $fieldName, $isForce );
		}
		// 读取默认
		return $this->getDefaultValue();
		*/
	}

	/**
	 * 获取数据(从缓存中获取)
	 * @param array $fieldNames
	 * @param bool $isForce 是否强制刷新数据访问。[false][默认]
	 * @return array|string|null [null]数据不存在
	 * @throws
	 */
	public function getsOfCache( array $fieldNames, bool $isForce = false ):array|string|null {
		return $this->getDataUnit()->gowDirectData()->getsOfCache( com\Lib\Fun\Str::parseNames( $fieldNames ), $isForce );
	}

	/**
	 * 获取已缓存的数据
	 * @return array
	 */
	public function getCacheDatas(  ):array {
		return $this->getDataUnit()->gowDirectData()->getCacheDatas();
	}

	/**
	 * 读取默认值
	 * @param string $fieldName
	 * @return mixed|null
	 */
	public function getDefaultValue( string $fieldName ) {
		return $this->goFieldStruct()->getDefaultValue( $fieldName );
	}

	/**
	 * 获取数据(从缓存中获取)(为空时抛出异常)
	 * @param string $fieldName
	 * @param bool $isForce 是否强制刷新数据访问。[false][默认]
	 * @return mixed
	 * @throws
	 */
	public function getOfCacheOrEmptyFail( string $fieldName, bool $isForce = false ):mixed {
		$data = $this->getOfCache( $fieldName, null, $isForce );
		if( $data === null ){
			throw com\Lib\Err\Exception::makeOfNew( '', com\Lib\Err\Code::$sysDataNotExist );
		}
		//
		return $data;
	}

	/**
	 * 获取数据(从缓存组中获取)(为空时抛出异常)
	 * @param string $fieldName
	 * @param bool $isForce 是否强制刷新数据访问。[false][默认]
	 * @return mixed
	 * @throws
	 */
	public function getOfCachesOrEmptyFail( string $fieldName, bool $isForce = false ):mixed {
		$data = $this->getOfCaches( $fieldName, null, $isForce );
		if( empty( $data ) ){
			throw com\Lib\Err\Exception::makeOfNew( '', com\Lib\Err\Code::$sysDataNotExist );
		}
		//
		return $data;
	}


	/**
	 * 设置数据
	 * @param string $fieldName
	 * @param mixed $value 数据
	 * @return mixed
	 */
	public function setOfCache( string $fieldName, mixed $value ):mixed {
		return $this->getDataUnit()->gowDirectData()->setOfCache( com\Lib\Fun\Str::parseName( $fieldName ), $value );
		/*
		// 如果有where则读取数据库
		if( $this->getDataUnit()->goDirectData()->isExistsWhere() ){
			return $this->getDataUnit()->goDirectData()->getOfCache( $fieldName, $isForce );
		}
		// 读取默认
		return $this->getDefaultValue();
		*/
	}

	/**
	 * 设置数据
	 * @param array $datas
	 * @return mixed
	 */
	public function setsOfCache( array $datas ):mixed {
		return $this->getDataUnit()->gowDirectData()->setsOfCache( com\Lib\Fun\Array_::keyNameToParseNamesAsUnderline( $datas ) );
	}

	/**
	 * 获取一列数据
	 * @param string $fieldName
	 * @return com\Lib\Utils\Helper\Array_
	 */
	public function pluck( string $fieldName ):com\Lib\Utils\Helper\Array_ {
		// $this->getDataUnit()->goModelQuery()->pluck( $fieldName )->mapToDictionary();
		$data = $this->getDataUnit()->goModelQuery()->pluck( com\Lib\Fun\Str::parseName( $fieldName ) )->toArray();
		return com\Lib\Utils\Helper\Array_::make( $data );
	}

	/**
	 * 获取一列数据并合并为一个有序ids数组
	 * @param string $fieldName
	 * @return com\Lib\Utils\Helper\Array_
	 */
	public function pluckOfContinuousIds( string $fieldName ):com\Lib\Utils\Helper\Array_ {
		$continuousIds = [];
		foreach( $this->pluck( com\Lib\Fun\Str::parseName( $fieldName ) )->toArray() as $data ){
			$continuousIds = array_merge( $continuousIds, com\Lib\Fun\Array_::toArray( $data ) );
		}
		//
		return com\Lib\Utils\Helper\Array_::make( $continuousIds )->unique()->sortOfAsc();
	}

	/**
	 * 检查指定对是否存在GoDirectData
	 * @param string $fieldName
	 * @param $classObj
	 * @return bool
	 */
	/*
	private function isExists_GoDirectData( $classObj ):bool {
		return method_exists( $classObj, 'goDirectData' );
	}
	*/

	/**
	 * 是否已上锁
	 * @param string $fieldName
	 * @return bool
	 */
	public function isLock( string $fieldName ):bool {
		return $this->goFieldStruct()->isLock( $fieldName );
	}

	/**
	 * 上锁
	 * @param string $fieldName
	 * @return $this
	 */
	public function lock( string $fieldName ):self {
		$this->goFieldStruct()->lock( $fieldName );
		return $this;
	}

	/**
	 * 解锁
	 * @param string $fieldName
	 * @return $this
	 */
	public function unlock( string $fieldName ):self {
		$this->goFieldStruct()->lock( $fieldName );
		return $this;
	}

	/**
	 * 是否已设置
	 * @param string $fieldName
	 * @return bool
	 */
	public function isset( string $fieldName ):bool {
		//
		return $this->goFieldStruct()->isset( $fieldName );
	}

	/**
	 * 设置数据
	 * @param string $fieldName
	 * @param mixed $data 数据
	 * @return $this
	 */
	public function set( string $fieldName, mixed $data ):self {
		$this->goFieldStruct()->setValue( $fieldName, $data );
		//
		return $this;
	}
	/**
	 * 设置数据
	 * @param array $fieldDatas [ '{$fieldName}' => '{$data}', ... ]
	 * @return $this
	 */
	public function sets( array $fieldDatas ):self {
		foreach( $fieldDatas as $fieldKey => $fieldValue ){
			$this->goFieldStruct()->setValue( $fieldKey, $fieldValue );
		}
		//
		return $this;
	}

	/**
	 * 设置默认值
	 * @param string $fieldName
	 * @param mixed|\Closure $data 数据(支持传入数据闭关)
	 * @return $this
	 */
	public function setDefaultValue( string $fieldName, mixed $data ):self {
		$this->goFieldStruct()->setDefaultValue( $fieldName, $data );
		//
		return $this;
	}

	/**
	 * 设置json数据（完整覆盖）
	 * @param string $fieldName
	 * @param string $keyPath 为空时则写入首层
	 * @param mixed $data 数据
	 * @return $this
	 */
	public function setOfJsonArray( string $fieldName, string $keyPath, mixed $data ):self {
		$this->goFieldStruct()->setValueOfJsonArray( $fieldName, $keyPath, $data );
		//
		return $this;
	}

	/**
	 * 设置json数据(追加)
	 * @param string $fieldName
	 * @param string $keyPath 为空时则写入首层
	 * @param mixed $data 数据
	 * @return $this
	 */
	public function setOfJsonArrayAppend( string $fieldName, string $keyPath, mixed $data ):self {
		$this->goFieldStruct()->setValueOfJsonArrayAppend( $fieldName, $keyPath, $data );
		//
		return $this;
	}

	/**
	 * 设置json数据
	 * @param string $fieldName
	 * @param string $keyPath 为空时则写入首层
	 * @param mixed $data 数据
	 * @return $this
	 */
	public function setOfStringArray( string $fieldName, string $keyPath, mixed $data ):self {
		$this->goFieldStruct()->setValueOfStringArray( $fieldName, $keyPath, $data );
		//
		return $this;
	}

	/**
	 * 设置json数据(追加)
	 * @param string $fieldName
	 * @param string $keyPath 为空时则写入首层
	 * @param mixed $data 数据
	 * @return $this
	 */
	public function setOfStringArrayAppend( string $fieldName, string $keyPath, mixed $data ):self {
		$this->goFieldStruct()->setValueOfStringArrayAppend( $fieldName, $keyPath, $data );
		//
		return $this;
	}

	/**
	 * 设置数据
	 * @param string $fieldName
	 * @param array $ids 数据
	 * @return $this
	 */
	public function setOfContinuousIds( string $fieldName, array $ids ):self {
		return $this->set( $fieldName, com\Lib\Fun\Array_::toContinuousIdsAsString( $ids ) );
	}

	/**
	 * 设置数据(多条)
	 * @param string $fieldName
	 * @param array $manyString 数据
	 * @return $this
	 */
	public function setOfManyString( string $fieldName, array $manyString ):self {
		// 转字符串
		$idsStr = com\Lib\Fun\Array_::toStr( $manyString, [
			'hasSides' => true,
		] );
		//
		return $this->set( $fieldName, $idsStr );
	}

	/**
	 * 设置数据
	 * @param string $fieldName
	 * @param mixed $data 数据
	 * @return $this|null [null]设置已存在，设置失败
	 */
	public function setNx( string $fieldName, mixed $data ):?self {
		if( ! $this->isset( $fieldName ) ){
			return $this->set( $fieldName, $data );
		}
		return null;
	}

	/**
	 * 获取field（包含前缀）
	 * @param string $fieldName
	 * @return string
	 */
	public function getFieldAlias( string $fieldName ):string {
		return $this->getDataUnit()->buildFieldPrefix( com\Lib\Fun\Str::parseName( $fieldName ) );
	}

	/**
	 * 加入到field
	 * @param string $fieldName
	 * @return $this
	 */
	public function addField( string $fieldName ):self {
		$this->getDataUnit()->goField()->addField( $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ) );
		//
		return $this;
	}

	/**
	 * 加入到field
	 * @param string $fieldName
	 * @param string|null $as 别名
	 * @return $this
	 */
	public function addFieldAs( string $fieldName, string|null $as = null ):self {
		$this->getDataUnit()->goField()->addFieldAs( $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ), $as );
		//
		return $this;
	}

	/**
	 * 设置where条件
	 * @param string $fieldName
	 * @param mixed ...$args
	 * @return $this
	 */
	public function where( string $fieldName, ...$args ):self {
		$this->getDataUnit()->goModelQuery()->where( $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ), ...$args );
		//
		return $this;
	}

	/**
	 * 设置or where条件
	 * @param string $fieldName
	 * @param mixed ...$args
	 * @return $this
	 */
	public function orWhere( string $fieldName, ...$args ):self {
		$this->getDataUnit()->goModelQuery()->orWhere( $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ), ...$args );
		//
		return $this;
	}

	/**
	 * 设置where条件
	 * @param string $fieldName
	 * @param mixed ...$args
	 * @return $this
	 */
	public function whereOfJson( string $fieldName, ...$args ):self {
		$args[0] = $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ) . '->' . $args[0];
		$this->getDataUnit()->goModelQuery()->where( ...$args );
		//
		return $this;
	}

	/**
	 * 设置where条件
	 * @param string $fieldName
	 * @param mixed ...$args
	 * @return $this
	 */
	public function whereJsonContains( string $fieldName, ...$args ):self {
		$args[0] = $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ) . '->' . $args[0];
		$this->getDataUnit()->goModelQuery()->whereJsonContains( ...$args );
		//
		return $this;
	}

	/**
	 * 设置where = 条件
	 * @param string $fieldName
	 * @param mixed $value
	 * @return $this
	 */
	public function whereEq( string $fieldName, mixed $value ):self {
		$this->getDataUnit()->goModelQuery()->where( $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ), '=', $value );
		//
		return $this;
	}

	/**
	 * 设置where != 条件
	 * @param string $fieldName
	 * @param mixed $value
	 * @return $this
	 */
	public function whereNotEq( string $fieldName, mixed $value ):self {
		$this->getDataUnit()->goModelQuery()->where( $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ), '!=', $value );
		//
		return $this;
	}

	/**
	 * 设置where LIKE 条件
	 * @param string $fieldName
	 * @param mixed $value
	 * @return $this
	 */
	public function whereLike( string $fieldName, mixed $value ):self {
		$this->getDataUnit()->goModelQuery()->where( $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ), 'LIKE', $value );
		//
		return $this;
	}

	/**
	 * 设置where LIKE 条件(ids条件)
	 * @param string $fieldName
	 * @param int $value ids
	 * @return $this
	 */
	public function whereLikeOfContinuousId( string $fieldName, int $value ):self {
		$this->getDataUnit()->goModelQuery()->where( $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ), 'LIKE', "%,{$value},%" );
		//
		return $this;
	}

	/**
	 * 设置 or where LIKE 条件(ids条件)
	 * @param string $fieldName
	 * @param int $value ids
	 * @return $this
	 */
	public function orWhereLikeOfContinuousId( string $fieldName, int $value ):self {
		$this->getDataUnit()->goModelQuery()->orWhere( $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ), 'LIKE', "%,{$value},%" );
		//
		return $this;
	}

	/**
	 * 设置where LIKE 条件（连续的ids）
	 * @param string $fieldName
	 * @param array $value 连续的ids。如传入[ 2, 5 ]，则like条件为：'%,2,%,5,%'
	 * @return $this
	 */
	public function whereLikeOfContinuousIds( string $fieldName, array $value ):self {
		$likeStr = '%,' . implode( ',%,', $value ) . ',%';
		$this->getDataUnit()->goModelQuery()->where( $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ), 'LIKE', $likeStr );
		//
		return $this;
	}

	/**
	 * 设置where in 条件
	 * @param string $fieldName
	 * @param array|\Closure $inData
	 * @return $this
	 */
	public function whereIn( string $fieldName, array|\Closure $inData ):self {
		$this->getDataUnit()->goModelQuery()->whereIn( $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ), $inData );
		//
		return $this;
	}

	/**
	 * 设置where not in 条件
	 * @param string $fieldName
	 * @param array|\Closure $inData
	 * @return $this
	 */
	public function whereNotIn( string $fieldName, array|\Closure $inData ):self {
		$this->getDataUnit()->goModelQuery()->whereNotIn( $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ), $inData );
		//
		return $this;
	}

	/**
	 * Add an "order by" clause to the query.
	 * @param string $fieldName
	 * @param string $direction
	 * @return $this
	 */
	public function orderBy( string $fieldName, string $direction = 'asc' ):self {
		$this->getDataUnit()->goModelQuery()->orderBy( $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ), $direction );
		//
		return $this;
	}

	/**
	 * Add a descending "order by" clause to the query.
	 * @param string $fieldName
	 * @return $this
	 */
	public function orderByDesc( string $fieldName ):self {
		$this->getDataUnit()->goModelQuery()->orderByDesc( $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ) );
		//
		return $this;
	}

	/**
	 * Add a "group by" clause to the query.
	 * @param string $fieldName
	 * @return $this
	 */
	public function groupBy( string $fieldName ):self {
		$this->getDataUnit()->goModelQuery()->groupBy( [ $this->getFieldAlias( com\Lib\Fun\Str::parseName( $fieldName ) ) ] );
		//
		return $this;
	}

	/**
	 * 判断数据是否存在
	 * @param string $fieldName
	 * @return bool [false]不存在 [true]存在
	 * @throws
	 */
	public function isExist( string $fieldName ):bool {
		return $this->getDataUnit()->newSelf()->where( com\Lib\Fun\Str::parseName( $fieldName ), $this->getSetDataOrFail( $fieldName ) )->isExist();
		//
		// return $this->isExistToID( $fieldName ) ? true : false;
	}

	/**
	 * 判断数据是否存在，不存在则抛出异常
	 * @param string $fieldName
	 * @return bool
	 * @throws
	 */
	public function isExistOrFail( string $fieldName ):bool {
		if( $this->isExist( $fieldName ) ){
			return true;
		}else{
			throw com\Lib\Err\Exception::makeOfNew( '数据不存在', com\Lib\Err\Code::$sysDataNotExist );
		}
	}

	/**
	 * 判断数据是否存在，存在则返回主键id
	 * @return int|null [null]不存在 [>0]存在，并返回主键id
	 * @throws
	 */
	public function isExistToID():?int {
		return $this->get( 'id' );
		//
		// return $this->getDataUnit()->goModelQueryOfNew()->where( $fieldName, $this->get() )->value( 'id' );
	}

	/**
	 * 判断数据是否存在，存在则返回主键id，不存在则抛出异常
	 * @return int [>0]存在，并返回主键id
	 * @throws
	 */
	public function isExistToIDOrFail():int {
		$dataId = $this->isExistToID();
		if( $dataId === null ){
			throw com\Lib\Err\Exception::makeOfNew( '数据不存在', com\Lib\Err\Code::$sysDataNotExist );
		}
		return $dataId;
	}

	/**
	 * 保存自身(保存成功后销毁自身)
	 * @param string $fieldName
	 * @param bool $resetSelf 保存后是否销毁自身 [false]默认
	 * @return bool [true][必返]
	 */
	public function save( string $fieldName, bool $resetSelf = false ):bool {
		if( $this->goFieldStruct()->issetNewValue( $fieldName ) ){
			$this->getDataUnit()->goModelQueryCloneOfNew()->update( [
				$fieldName => $this->goFieldStruct()->getValueAsSqlData( $fieldName ),
			] );
		}
		// 清除自身数据
		if( $resetSelf ){
			$this->reset( $fieldName );
		}
		//
		return true;
	}

	/**
	 * 保存所有
	 * @param bool $resetSelf 保存后是否销毁自身 [false]默认
	 * @return bool [true][必返]
	 * @throws
	 */
	public function saves( bool $resetSelf = false ):bool {
		$hasDatas = $this->getUpdateData();
		if( ! empty( $hasDatas ) ){
			$this->getDataUnit()->goModelQueryCloneOfNew()->update( $hasDatas );
		}
		// 清除自身数据
		if( $resetSelf ){
			$this->reset();
		}
		//
		return true;
	}

	/**
	 * 获取所有已设置的数据
	 * @param bool $isGetDefaultValue 是否获取默认数据
	 * @param bool $keyNameType  [false][默认]将Java风格转换为C的风格 [true]将C风格转换为Java的风格
	 * @return array
	 * @throws
	 */
	public function getUpdateData( bool $isGetDefaultValue = false, bool $keyNameType = true ):array {
		$hasData = [];
		//
		$dataUnit = $this->getDataUnit()->newSelfCloneWhere();
		$structDatas = $this->goFieldStruct()->getChangeStructDatas( $isGetDefaultValue, $keyNameType );
		// 预加载数据
		foreach( $structDatas as $structKey => $structValue ){
			if(
				$structValue['type'] === nameDataOperates\FieldStruct::$varType_JsonArrayAppend
				|| $structValue['type'] === nameDataOperates\FieldStruct::$varType_StringArrayAppend
			){
				$dataUnit->newGetDatasOfCache()->callField( $structKey );
			}
		}
		if( $dataUnit->newGetDatasOfCache()->getPreCount() > 0 ){
			$preData = $dataUnit->newGetDatasOfCache()->gets();
			if( $preData === null ){
				$preData = [];
			}
		}else{
			$preData = [];
		}
		// 处理数据
		foreach( $structDatas as $fieldKey => $structValue ){
			$structValue['value'] = $structValue['value'] ?? $structValue['default'];
			switch( $structValue['type'] ){
				case nameDataOperates\FieldStruct::$varType_String:
					// 覆盖
					$hasData[ $fieldKey ] = $structValue['value'];
					break;
				case nameDataOperates\FieldStruct::$varType_JsonArray:
				case nameDataOperates\FieldStruct::$varType_StringArray:
					$hasData[ $fieldKey ] = com\Lib\Fun\Array_::toPathArrayDirectKey( $structValue['value'] );
					break;
				case nameDataOperates\FieldStruct::$varType_JsonArrayAppend:
					// 追加
					$hasData = com\Lib\Fun\Array_::arrayMerges( $hasData, nameDataOperate\JsonOfArray::makeOfNew( $fieldKey, $structValue['value'] )->getModelUpdateData( $preData[ $fieldKey ] ?? [] ) );
					break;
				case nameDataOperates\FieldStruct::$varType_StringArrayAppend:
					// 追加
					$hasData[ $fieldKey ] = $preData[ $fieldKey ] ?? [];
					foreach( $structValue['value'] as $valueKey => $valueVlue ){
						// Key为空时使用合并操作
						if( $valueKey === '' ){
							$hasData[ $fieldKey ] = com\Lib\Fun\Array_::arrayMerges( $hasData[ $fieldKey ], $valueVlue );
						}else{
							com\Lib\Fun\Array_::assignPathWrite( $hasData[ $fieldKey ], $valueKey, $valueVlue );
						}
					}
					break;
				default:
					throw com\Lib\Err\Exception::makeOfNew( '', com\Lib\Err\Code::$sysAssertError );
			}
		}
		//
		// d($hasData);
		return $hasData;
		// return $this->goFieldStruct()->getChangeDatas( $isGetDefaultValue, $keyNameType );
	}

	/**
	 * 重置自身
	 * @param string|null $fieldName
	 * @return $this
	 */
	public function reset( string|null $fieldName = null ):self {
		$this->goFieldStruct()->reset( $fieldName );
		//
		return $this;
	}


}